let ARRAY_METHOD = [
  "push",
  "pop",
  "shift",
  "unshift",
  "sort",
  "splice"
]

let array_methods = Object.create(Array.prototype);
ARRAY_METHOD.forEach(method => {
  array_methods[method] = function () {
    console.log('调用的是拦截的' + method + '方法');
    for (let i = 0; i < arguments.length; i++) {
      observe(arguments[i]/*this????*/)
    }

    let res = Array.prototype[method].apply(this, arguments)
    return res;
  }
})

function defineReactive(target, key, value, enumerable) {
  let that = this;
  if (typeof value === 'object' && value != null) {
    observe(value, this);
  }

  /* Dep实例化 */
  let dep = new Dep()

  Object.defineProperty(target, key, {
    configurable: true,
    enumerable: !!enumerable,
    get() {
      console.log('读取o的' + key + '属性');
      // 依赖收集
      dep.depend()
      return value
    },
    set(newVal) {
      console.log('设置o的' + key + '属性为：' + newVal);
      if(typeof newVal === 'object' && newVal != null) {
        observe(newVal /*, vm实例*/);
      }
      value = newVal;

      // 派发更新，找到全局的watcher，调用update
      dep.notify()
    }
  })
}

function observe(obj, vm) {
  if(Array.isArray(obj)) {
    for(let i=0;i<obj.length;i++) {
      observe(obj[i], vm);
    }
  } else {
    let keys = Object.keys(obj);
    for(let i=0;i<keys.length;i++) {
      let prop = keys[i];
      defineReactive.call(vm, obj, prop, obj[prop], true)
    }
  }
}

function proxy(target, prop, key) {
  Object.defineProperty(target, key, {
      enumerable: true,
      configurable: true,
      set(newVal) {
        target[prop][key] = newVal;
      },
      get() {
        return target[prop][key]
      }
    })
}

JGVue.prototype.initData = function () {
  let keys = Object.keys(this._data);
  observe(this._data, this)


  for(let i=0;i<keys.length;i++) {
    proxy(this, '_data', keys[i])
  }
}



